package site.timers.chat.advice;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import site.timers.chat.exception.ApplicationException;
import site.timers.chat.pojo.Result;

/**
 * @className: ExceptionAdvice
 * @author: twl
 * @date: 2024/12/16 10:03
 * @version: 1.0
 * @description: 全局异常处理
 */
@Slf4j
@ControllerAdvice
public class ExceptionAdvice {

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Result<?> exceptionHandler(Exception e) {
        log.error("未知异常，msg={}", e.getMessage(), e);
        return Result.error("服务异常");
    }

    @ResponseBody
    @ExceptionHandler(value = ApplicationException.class)
    public ResponseEntity<Result<?>> applicationExceptionHandler(Exception e) {
        log.error("业务异常, msg={}", e.getMessage(), e);
        ApplicationException ae = (ApplicationException) e;
        return ResponseEntity.status(ae.getCode()).body(Result.error(ae));
    }

    /**
     * 处理请求参数格式错误 @RequestBody上使用@Valid 实体上使用@NotNull等，验证失败后抛出的异常是MethodArgumentNotValidException异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<?> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        log.error("参数格式异常，msg={}", e.getMessage(), e);
        return Result.error(e.getMessage());
    }

    /**
     * 处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    @ExceptionHandler(BindException.class)
    public Result<?> bindExceptionHandler(BindException e) {
        log.error("参数格式异常，msg={}", e.getMessage(), e);
        return Result.error(e.getMessage());
    }

//    /**
//     * 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是ConstraintViolationException
//     */
//    @ResponseStatus(HttpStatus.BAD_REQUEST)
//    @ResponseBody
//    @ExceptionHandler(ConstraintViolationException.class)
//    public Result<?> constraintViolationExceptionHandler(ConstraintViolationException e) {
//        log.error("参数格式异常，msg={}", e.getMessage(), e);
//        return Result.error(e.getMessage());
//    }

    /**
     * 参数格式异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result<?> httpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
        log.error("参数格式异常，msg={}", e.getMessage(), e);
        return Result.error(e.getMessage());
    }

    /**
     * 请求方法异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result<?> httpRequestMethodNotSupportedExceptionHandler(HttpRequestMethodNotSupportedException e) {
        log.error("请求方法异常，msg={}", e.getMessage(), e);
        return Result.error(e.getMessage());
    }
}
